package data

import (
	protoV1 "Cosmos.Communication/api/v1"
	protoV2 "Cosmos.Communication/api/v2"
	"Cosmos.Communication/infrastructure/grpc"
	"Cosmos.Communication/infrastructure/queue"
	"Cosmos.Communication/internal/biz"
	"Cosmos.Communication/internal/conf"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/google/wire"
)

// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewData, NewDataSet, NewHealth, NewInvoke, NewNotify)

// Data .
type Data struct {
	queue         queue.Queue
	clientfactory *grpcClientFactory
	logHelper     *log.Helper
}

// NewData .
func NewData(conf *conf.Config, logger log.Logger) (data *Data, cleanup func(), err error) {
	data = &Data{}

	data.logHelper = log.NewHelper(logger)

	var queueOptions = &queue.QueueOptions{Limit: 10000}
	data.queue = queue.NewBlockingQueue(queueOptions, logger)

	var grpcOptions = &grpc.GrpcConnOptions{Network: conf.Vendor.Grpc.Network, Addr: conf.Vendor.Grpc.Addr}
	if data.clientfactory, err = NewGrpcClientFactory(grpcOptions); err != nil {
		return
	}

	cleanup = data.Close
	return data, cleanup, nil
}

func (d *Data) GetDataSetGrpcClient() (client protoV2.RpcDataSetServiceClient, err error) {
	return d.clientfactory.GetDataSetGrpcClient()
}

func (d *Data) GetVendorRuntimeGrpcClient() (client protoV1.VendorRuntimeServiceClient, err error) {
	return d.clientfactory.GetVendorRuntimeGrpcClient()
}

func (d *Data) PushDataFrame(dataframe *biz.DataFrame) {
	d.queue.Push(dataframe)
}

func (d *Data) PollDataFrame() (dataframe *biz.DataFrame) {
	var data = d.queue.Poll()
	return data.(*biz.DataFrame)
}

func (d *Data) Close() {
	d.logHelper.Info("closing the data resources")
	d.clientfactory.Close()
}
